home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload Trio 2 / Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO / dir37 / ms_sh23s.zip / SRC / PTYPE.C < prev    next >
C/C++ Source or Header  |  1994-08-26  |  7KB  |  298 lines

  1. /*
  2.  * MS-DOS SHELL - Copyright (c) 1990,4 Data Logic Limited
  3.  *
  4.  * This code is subject to the following copyright restrictions:
  5.  *
  6.  * 1.  Redistribution and use in source and binary forms are permitted
  7.  *     provided that the above copyright notice is duplicated in the
  8.  *     source form and the copyright notice in file sh6.c is displayed
  9.  *     on entry to the program.
  10.  *
  11.  * 2.  The sources (or parts thereof) or objects generated from the sources
  12.  *     (or parts of sources) cannot be sold under any circumstances.
  13.  *
  14.  *    $Header: /usr/users/istewart/shell/sh2.3/Release/RCS/ptype.c,v 1.2 1994/08/25 20:49:11 istewart Exp $
  15.  *
  16.  *    $Log: ptype.c,v $
  17.  * Revision 1.2  1994/08/25  20:49:11  istewart
  18.  * MS Shell 2.3 Release
  19.  *
  20.  * Revision 1.1  1994/02/23  09:23:38  istewart
  21.  * Beta 233 updates
  22.  *
  23.  *
  24.  */
  25.  
  26. #include <sys/types.h>
  27. #include <sys/stat.h>
  28. #include <stdio.h>
  29. #include <signal.h>
  30. #include <errno.h>
  31. #include <setjmp.h>
  32. #include <stdlib.h>
  33. #include <fcntl.h>
  34. #include <string.h>
  35. #include <unistd.h>
  36. #include <limits.h>
  37. #include <dirent.h>
  38. #include <ctype.h>
  39. #include "sh.h"
  40.  
  41. static unsigned long        QueryApplicationType1 (int);
  42. static void            WhenceType (char *path);
  43. unsigned long            QueryApplicationType (const char *);
  44.  
  45. /*
  46.  * Find out the application type
  47.  */
  48.  
  49. unsigned long    QueryApplicationType (const char *pathname)
  50. {
  51.     int            fd;
  52.     unsigned long    res;
  53.     size_t        len;
  54.  
  55.     if (pathname == NULL)
  56.     return EXETYPE_BAD_FILE;
  57.     
  58. /* Open the file */
  59.  
  60.     if ((fd = open (pathname, O_RDONLY | O_BINARY)) == -1)
  61.     return EXETYPE_BAD_FILE;
  62.  
  63.     res = QueryApplicationType1 (fd);
  64.     close (fd);
  65.  
  66. /* Check for .com file */
  67.  
  68.     if ((res == EXETYPE_UNKNOWN) &&
  69.     ((len = strlen (pathname)) > 5) &&
  70.         (stricmp (&pathname[len - 4], ".com") == 0))
  71.     return EXETYPE_DOS_CUI;
  72.  
  73.     return res;
  74. }
  75.  
  76. /*
  77.  * Do the actual work!
  78.  */
  79.  
  80. static unsigned long QueryApplicationType1 (int fd)
  81. {
  82.     union {
  83.     struct ExecOS2_16Header    OS2aHead;
  84.     struct ExecOS2_32header    OS2bHead;
  85.     struct ExecNTHeader    NTHead;
  86.     struct ExecDosHeader    DosHead;
  87.     }                OS_Headers;
  88.     struct stat            fstatus;
  89.  
  90.     if ((read (fd, &OS_Headers, sizeof (struct ExecDosHeader)) !=
  91.         sizeof (struct ExecDosHeader)) ||
  92.         (OS_Headers.DosHead.e_magic != SIG_DOS))
  93.     return EXETYPE_UNKNOWN;
  94.     
  95. /*
  96.  * If the header size in the header is not a new header or the relocation
  97.  * section starts before the end of the new header, it must be a DOS program
  98.  */
  99.  
  100.     if ((OS_Headers.DosHead.e_cparhdr * 16 < sizeof (struct ExecDosHeader)) ||
  101.     (OS_Headers.DosHead.e_lfarlc < sizeof (struct ExecDosHeader)))
  102.         return EXETYPE_DOS_CUI;
  103.     
  104.     if ((fstat (fd, &fstatus) == -1) ||
  105.     (fstatus.st_size < (off_t) OS_Headers.DosHead.e_lfanew))
  106.         return EXETYPE_DOS_CUI;
  107.  
  108.     if ((lseek (fd, (off_t) OS_Headers.DosHead.e_lfanew, SEEK_SET) ==
  109.         (off_t) -1) ||
  110.     (read (fd, &OS_Headers, sizeof (OS_Headers)) != sizeof (OS_Headers)))
  111.     return EXETYPE_BAD_IMAGE;
  112.     
  113. /*
  114.  * Check for NT
  115.  */
  116.  
  117.     if (OS_Headers.NTHead.Signature == SIG_NT)
  118.     {
  119.     if (OS_Headers.NTHead.FileHeader.SizeOfOptionalHeader !=
  120.         NT_OPTIONAL_HEADER)
  121.         return EXETYPE_UNKNOWN;
  122.  
  123.     switch (OS_Headers.NTHead.OptionalHeader.Subsystem)
  124.     {
  125.         default:
  126.         return EXETYPE_UNKNOWN;
  127.  
  128.         case NT_SS_NATIVE:
  129.         return EXETYPE_NT_NATIVE;
  130.  
  131.         case NT_SS_WINDOWS_GUI:
  132.         return EXETYPE_NT_WINDOWS_GUI;
  133.  
  134.         case NT_SS_WINDOWS_CUI:
  135.         return EXETYPE_NT_WINDOWS_CUI;
  136.  
  137.         case NT_SS_OS2_CUI:
  138.         return EXETYPE_NT_OS2;
  139.  
  140.         case NT_SS_POSIX_CUI:
  141.         return EXETYPE_NT_POSIX;
  142.     }
  143.     }
  144.  
  145. /* OS2 1.x */
  146.  
  147.     else if ((OS_Headers.OS2aHead.ne_magic == SIG_OS2_16) ||
  148.          (OS_Headers.OS2aHead.ne_magic == SIG_OS2_16LE))
  149.     {
  150.         printf ("ne_flags       = %.4x  ne_flagsothers = %.4x (Win Ver %d)\n",
  151.          OS_Headers.OS2aHead.ne_flags,
  152.          OS_Headers.OS2aHead.ne_flagsothers,
  153.          OS_Headers.OS2aHead.ne_expver);
  154.         printf ("ne_exetyp      = %.4x (R %.2x V %.2x)\n",
  155.          OS_Headers.OS2aHead.ne_exetyp,
  156.          OS_Headers.OS2aHead.ne_ver,
  157.          OS_Headers.OS2aHead.ne_rev);
  158.  
  159.     if (OS_Headers.OS2aHead.ne_flags & (OS2_16_NOTP | OS2_16_IERR))
  160.         return EXETYPE_BAD_IMAGE;
  161.  
  162.     if (OS_Headers.OS2aHead.ne_exetyp == OS2_16_WINDOWS)
  163.         return EXETYPE_DOS_GUI;
  164.  
  165. /* This appears to be what Watcom generates */
  166.  
  167.     else if ((OS_Headers.OS2aHead.ne_exetyp == OS2_16_UNKNOWN) &&
  168.          (OS_Headers.OS2aHead.ne_flags == 0))
  169.         return EXETYPE_DOS_32;
  170.  
  171.  
  172. /* Under OS/2, A bound app is an OS/2 app otherwise its a DOS app */
  173.  
  174. #if (OS_TYPE != OS_OS2)
  175.     else if (OS_Headers.OS2aHead.ne_exetyp == OS2_16_UNKNOWN)
  176.         return EXETYPE_DOS_CUI;
  177.  
  178.     else if (OS_Headers.OS2aHead.ne_flags & OS2_16_BOUND)
  179.         return EXETYPE_DOS_BOUND;
  180. #else
  181.     else if (OS_Headers.OS2aHead.ne_exetyp == OS2_16_UNKNOWN)
  182.         return EXETYPE_OS2_CUI;
  183. #endif
  184.  
  185. /* Real OS/2 app */
  186.  
  187.     else if (OS_Headers.OS2aHead.ne_exetyp == OS2_16_OS2)
  188.     {
  189.         switch (OS_Headers.OS2aHead.ne_flags & OS2_16_APPTYP)
  190.         {
  191.             case OS2_16_NOTWINCOMPAT:
  192.             return EXETYPE_OS2_CUI;
  193.  
  194.         case OS2_16_WINCOMPAT:
  195.             return EXETYPE_OS2_CGUI;
  196.  
  197.         case OS2_16_WINAPI:
  198.             return EXETYPE_OS2_GUI;
  199.  
  200.         case 0:
  201. #if (OS_TYPE == OS_OS2)
  202.             return EXETYPE_OS2_CUI;
  203. #else
  204.             return EXETYPE_DOS_BOUND;
  205. #endif
  206.         }
  207.     }
  208.     }
  209.  
  210. /* OS2 2.x */
  211.  
  212.     else if (OS_Headers.OS2bHead.e32_magic == SIG_OS2_32)
  213.     {
  214.         printf ("Mflags = %.8lx\n", OS_Headers.OS2bHead.e32_mflags);
  215.  
  216.         if ((OS_Headers.OS2bHead.e32_mflags & (OS2_NOTP | OS2_NOLOAD)) ||
  217.         (OS_Headers.OS2bHead.e32_mflags & OS2_MODMASK))
  218.         return EXETYPE_NOT_EXE;
  219.     
  220.     if ((OS_Headers.OS2bHead.e32_mflags & OS2_APPMASK) == OS2_NOPMW)
  221.         return EXETYPE_OS2_CUI | EXETYPE_OS2_32;
  222.  
  223.     else if ((OS_Headers.OS2bHead.e32_mflags & OS2_APPMASK) == OS2_PMW)
  224.         return EXETYPE_OS2_CGUI | EXETYPE_OS2_32;
  225.  
  226.     else if ((OS_Headers.OS2bHead.e32_mflags & OS2_APPMASK) == OS2_PMAPI)
  227.         return EXETYPE_OS2_GUI | EXETYPE_OS2_32;
  228.     }
  229.  
  230. /* Give UP! */
  231.  
  232.     return EXETYPE_UNKNOWN;
  233. }
  234.  
  235. /*
  236.  * Output file type
  237.  */
  238.  
  239. static char     *ExeType_Error[] = {
  240.     "Not known",
  241.     "Bad image",
  242.     "Not executable",
  243.     "File not found"
  244. };
  245.  
  246. static char    *ExeType_Dos[] = {
  247.     "DOS Character",
  248.     "Windows 16-bit",
  249.     "Watcom 32 bit",
  250.     "OS/2 Bound"
  251. };
  252.  
  253. static char    *ExeType_OS2[] = {
  254.    "Not PM compatible",
  255.    "PM compatible",
  256.    "PM"
  257. };
  258.  
  259. static char    *ExeType_NT[] = {
  260.     "Native",
  261.     "Windows GUI",
  262.     "Windows CUI",
  263.     "OS2",
  264.     "POSIX"
  265. };
  266.  
  267. static void WhenceType (char *path)
  268. {
  269.     unsigned long type = QueryApplicationType (path);
  270.    
  271.     printf ("%s [", path);
  272.  
  273.     if (type & EXETYPE_ERROR)
  274.     printf (ExeType_Error [type - 1]);
  275.  
  276.     else if (type & EXETYPE_DOS)
  277.     printf (ExeType_Dos [(type >> 4) - 1]);
  278.  
  279.     else if (type & EXETYPE_OS2)
  280.     printf ("OS2 %dbit %s", (type & EXETYPE_OS2_32) ? 32 : 16,
  281.          ExeType_OS2 [((type & EXETYPE_OS2_TYPE) >> 8) - 1]);
  282.  
  283.     else if (type & EXETYPE_NT)
  284.     printf ("Win NT %s subsystem", ExeType_NT [(type >> 12) - 1]);
  285.  
  286.     printf ("]\n");
  287. }
  288.  
  289. void    main (int argc, char **argv)
  290. {
  291.     int        i;
  292.  
  293.     for (i = 1; i < argc; i++)
  294.     WhenceType (argv[i]);
  295.  
  296.     exit (0);
  297. }
  298.